﻿namespace AB.ServiceDirectory.Dao
{
    using System;
    using System.Data.SqlClient;
    using System.Linq;
    using Commons.DataFilters;
    using Entities;

    /// <summary>
    /// TeamDao Class
    /// </summary>
    [Serializable]
    public class TeamDao
    {
        /// <summary>
        /// Data context
        /// </summary>
        [NonSerialized]
        private readonly ServicesDirectoryDataContext _context = DB.Context;

        /// <summary>
        /// Gets the list.
        /// </summary>
        /// <param name="filter">The filter.</param>
        /// <param name="sortType">Type of the sort.</param>
        /// <param name="startRowIndex">Start index of the row.</param>
        /// <param name="max">The max.</param>
        /// <returns></returns>
        public IQueryable<Team> GetList(TeamFilter filter, string sortType, int startRowIndex, int max)
        {
            IQueryable<Team> data = from t in _context.Teams select t;

            // 1. Filter by condition
            if (filter != null)
            {
                data = GetListQuery(data, filter);
            }

            // 2. Sorting
            data = GetListSort(data, sortType);

            // 3. Limit the rows
            data = data.Skip(startRowIndex).Take(max);

            //return data
            return data;
        }

        /// <summary>
        /// Gets the list sort.
        /// </summary>
        /// <param name="data">The data.</param>
        /// <param name="sortType">Type of the sort.</param>
        /// <returns></returns>
        private static IQueryable<Team> GetListSort(IQueryable<Team> data, string sortType)
        {
            bool sortDescending = false;
            if (!string.IsNullOrEmpty(sortType))
            {
                string[] values = sortType.Split(' ');
                sortType = values[0];

                if (values.Length > 1)
                {
                    sortDescending = (values[1] == "DESC");
                }

                switch (sortType)
                {
                    case "TeamName":
                        data = sortDescending
                                   ? data.OrderByDescending(t => t.TeamName)
                                   : data.OrderBy(t => t.TeamName);
                        break;

                    case "Address":
                        data = sortDescending
                                   ? data.OrderByDescending(t => t.Address.AddressLine)
                                   : data.OrderBy(t => t.Address.AddressLine);
                        break;

                    case "Postcode":
                        data = sortDescending
                                   ? data.OrderByDescending(t => t.Address.Postcode)
                                   : data.OrderBy(t => t.Address.Postcode);
                        break;

                    case "Contact":
                        data = sortDescending
                                   ? data.OrderByDescending(t => t.Contact.FirstName).ThenBy(t => t.Contact.Surname)
                                   : data.OrderBy(t => t.Contact.FirstName).ThenBy(t => t.Contact.Surname);
                        break;

                    case "IsActive":
                        data = sortDescending
                                   ? data.OrderByDescending(t => t.IsActive)
                                   : data.OrderBy(t => t.IsActive);
                        break;
                    default:
                        data = sortDescending
                                   ? data.OrderByDescending(t => t.TeamId)
                                   : data.OrderBy(t => t.TeamId);
                        break;
                }
            }
            return data;
        }

        /// <summary>
        /// Gets the list query.
        /// </summary>
        /// <param name="data">The data.</param>
        /// <param name="filter">The filter.</param>
        /// <returns></returns>
        private static IQueryable<Team> GetListQuery(IQueryable<Team> data, TeamFilter filter)
        {
            data = data.Where(t => t.DepartmentId == filter.DepartmentId);

            if (filter.BeginningLetters != null)
            {
                data = data.Where(t => filter.BeginningLetters.Contains(t.TeamName[0].ToString()));
            }

            if (!filter.IncludeInactive)
            {
                data = data.Where(t => t.IsActive == !filter.IncludeInactive);
            }
            return data;
        }

        /// <summary>
        /// Gets the list count.
        /// </summary>
        /// <param name="filter">The filter.</param>
        /// <returns></returns>
        public int GetListCount(TeamFilter filter)
        {
            IQueryable<Team> data = from t in _context.Teams
                                    select t;
            return GetListQuery(data, filter).Count();
        }

        /// <summary>
        /// Gets the team by id.
        /// </summary>
        /// <param name="id">The id.</param>
        /// <returns></returns>
        public Team GetTeamById(int id)
        {
            Team team = _context.Teams.FirstOrDefault(t => t.TeamId == id);
            return team;
        }

        /// <summary>
        /// Adds the team.
        /// </summary>
        /// <param name="team">The team.</param>
        /// <returns></returns>
        public bool AddTeam(Team team)
        {
            try
            {
                _context.Teams.InsertOnSubmit(team);
                _context.SubmitChanges();
                return true;
            }
            catch (SqlException e)
            {
                Log.GetLog(this).Error(e);
                return false;
            }
        }

        /// <summary>
        /// Edits the team.
        /// </summary>
        /// <param name="team">The team.</param>
        /// <returns></returns>
        public bool EditTeam(Team team)
        {
            BusinessType businessType = team.BusinessId != null
                                            ? _context.BusinessTypes.FirstOrDefault(b => b.BusinessId == team.BusinessId)
                                            : null;
            Contact contact = team.ContactId != null
                                  ? _context.Contacts.FirstOrDefault(c => c.ContactId == team.ContactId)
                                  : null;
            Address address = team.AddressId != null
                                  ? _context.Addresses.FirstOrDefault(a => a.AddressId == team.AddressId)
                                  : null;
            Country country = team.CountryId != null
                                  ? _context.Countries.FirstOrDefault(c => c.CountryId == team.CountryId)
                                  : null;

            try
            {
                //get team for editing
                Team editingTeam = _context.Teams.FirstOrDefault(t => t.TeamId == team.TeamId);

                if (editingTeam != null)
                {
                    editingTeam.TeamName = team.TeamName;
                    editingTeam.BusinessType = businessType;
                    editingTeam.Address = address;
                    editingTeam.Contact = contact;
                    editingTeam.ShortDescription = team.ShortDescription;
                    editingTeam.FullDescription = team.FullDescription;
                    editingTeam.CityTown = team.CityTown;
                    editingTeam.Country = team.Country;
                    editingTeam.PhoneNumber = team.PhoneNumber;
                    editingTeam.Fax = team.Fax;
                    editingTeam.Email = team.Email;
                    editingTeam.WebAddress = team.WebAddress;

                    editingTeam.BusinessType = businessType;
                    editingTeam.Contact = contact;
                    editingTeam.Address = address;
                    editingTeam.Country = country;

                    _context.SubmitChanges();
                    return true;
                }
            }
            catch (SqlException e)
            {
                Log.GetLog(this).Error(e);
                return false;
            }
            return false;
        }

        /// <summary>
        /// Sets the team status.
        /// </summary>
        /// <param name="teamId">The team id.</param>
        /// <param name="status">if set to <c>true</c> [status].</param>
        public void SetTeamStatus(int teamId, bool status)
        {
            Team team = _context.Teams.FirstOrDefault(t => t.TeamId == teamId);
            if (team != null)
            {
                team.IsActive = status;
                _context.SubmitChanges();
            }
        }
    }
}